home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 April
/
EnigmA AMIGA RUN 06 (1996)(G.R. Edizioni)(IT)[!][issue 1996-04][Skylink CD V].iso
/
earcd
/
utilgfx
/
raylab.lha
/
RayLab
/
source
/
objects.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-04
|
6KB
|
242 lines
/*
name: objects.c
Various object routines
-----------------------
*/
#include <stdlib.h>
#include "defs.h"
#include "extern.h"
/*****************************************************************
*
* Calculate the surface-normal for a given point and shape
*
*****************************************************************/
void GetSurfaceNormal(VECTOR *SurfNorm, POINT *SurfPoint, OBJECT *Object)
{
PLANE *p;
SPHERE *s;
ELLIPSOID *e;
TRIANGLE *t;
BOX *b;
DISC *d;
CYLINDER *c;
long i;
POINT ReTransformedPoint;
VECTOR tempv;
double tempd;
CopyPoint(&ReTransformedPoint,SurfPoint);
if(Object->Transform.NumTransforms>0) { /* Retransform the surface point */
for(i=Object->Transform.NumTransforms-1L;i>=0L;i--) {
/* for(i=0;i<Object->Transform.NumTransforms;i++) { */
switch(Object->Transform.Entry[i].Type) {
case TRANSFORM_SCALE:
ReTransformedPoint.x=ReTransformedPoint.x/Object->Transform.Entry[i].Values.x;
ReTransformedPoint.y=ReTransformedPoint.y/Object->Transform.Entry[i].Values.y;
ReTransformedPoint.z=ReTransformedPoint.z/Object->Transform.Entry[i].Values.z;
break;
case TRANSFORM_MOVE:
ReTransformedPoint.x=ReTransformedPoint.x-Object->Transform.Entry[i].Values.x;
ReTransformedPoint.y=ReTransformedPoint.y-Object->Transform.Entry[i].Values.y;
ReTransformedPoint.z=ReTransformedPoint.z-Object->Transform.Entry[i].Values.z;
break;
case TRANSFORM_ROTATE:
NegVector(&tempv,&Object->Transform.Entry[i].Values);
RotatePoint(&ReTransformedPoint,&tempv);
break;
case TRANSFORM_NONE:
default:
break;
}
}
}
switch(Object->ShapeType) {
case SHAPE_PLANE:
p=(PLANE *)(Object->Shape);
CopyVector(SurfNorm,&(p->Normal));
break;
case SHAPE_SPHERE:
s=(SPHERE *)(Object->Shape);
SurfNorm->x=ReTransformedPoint.x-s->Centre.x;
SurfNorm->y=ReTransformedPoint.y-s->Centre.y;
SurfNorm->z=ReTransformedPoint.z-s->Centre.z;
break;
case SHAPE_ELLIPSOID:
e=(ELLIPSOID *)(Object->Shape);
SurfNorm->x=(ReTransformedPoint.x-e->Centre.x)/(e->Radius.x*e->Radius.x);
SurfNorm->y=(ReTransformedPoint.y-e->Centre.y)/(e->Radius.y*e->Radius.y);
SurfNorm->z=(ReTransformedPoint.z-e->Centre.z)/(e->Radius.z*e->Radius.z);
break;
case SHAPE_TRIANGLE:
t=(TRIANGLE *)(Object->Shape);
CopyVector(SurfNorm,&(t->Plane.Normal));
break;
case SHAPE_BOX:
b=(BOX *)(Object->Shape);
if(ReTransformedPoint.x<(b->Corners[0].x+EPSILON)) /* minx */
CopyVector(SurfNorm,&b->Planes[0].Normal);
else if(ReTransformedPoint.x>(b->Corners[1].x-EPSILON)) /* maxx */
CopyVector(SurfNorm,&b->Planes[1].Normal);
else if(ReTransformedPoint.y<(b->Corners[0].y+EPSILON)) /* miny */
CopyVector(SurfNorm,&b->Planes[2].Normal);
else if(ReTransformedPoint.y>(b->Corners[1].y-EPSILON)) /* maxy */
CopyVector(SurfNorm,&b->Planes[3].Normal);
else if(ReTransformedPoint.z<(b->Corners[0].z+EPSILON)) /* minz */
CopyVector(SurfNorm,&b->Planes[4].Normal);
else if(ReTransformedPoint.z>(b->Corners[1].z-EPSILON)) /* maxz */
CopyVector(SurfNorm,&b->Planes[5].Normal);
break;
case SHAPE_DISC:
d=(DISC *)(Object->Shape);
CopyVector(SurfNorm,&(d->Plane.Normal));
break;
case SHAPE_CYLINDER:
c=(CYLINDER *)(Object->Shape);
tempd=ReTransformedPoint.x*ReTransformedPoint.x+ReTransformedPoint.y*ReTransformedPoint.y;
if(sqrt(tempd)>(c->r-EPSILON)) {
SurfNorm->x=ReTransformedPoint.x;
SurfNorm->y=ReTransformedPoint.y;
SurfNorm->z=0.0;
}
else {
if(ReTransformedPoint.z<(c->Ends[1].z-EPSILON))
CopyVector(SurfNorm,&c->Discs[0].Plane.Normal);
else CopyVector(SurfNorm,&c->Discs[1].Plane.Normal);
}
break;
}
if(Object->Transform.NumTransforms>0) { /* Transform the surface normal */
/* for(i=Object->Transform.NumTransforms-1L;i>=0L;i--) { */
for(i=0L;i<Object->Transform.NumTransforms;i++) {
switch(Object->Transform.Entry[i].Type) {
case TRANSFORM_SCALE:
SurfNorm->x=SurfNorm->x/Object->Transform.Entry[i].Values.x;
SurfNorm->y=SurfNorm->y/Object->Transform.Entry[i].Values.y;
SurfNorm->z=SurfNorm->z/Object->Transform.Entry[i].Values.z;
break;
case TRANSFORM_ROTATE:
CopyVector(&tempv,&Object->Transform.Entry[i].Values);
RevRotateVector(SurfNorm,&tempv);
break;
case TRANSFORM_MOVE:
case TRANSFORM_NONE:
default:
break;
}
}
}
}
/*****************************************************************
*
* Free all memory occupied by object-descriptions
*
*****************************************************************/
void FreeAllObjectMemory(void)
{
long i;
if(NumObjects>0) {
for(i=0;i<NumObjects;i++) {
switch(ObjectArray[i]->ShapeType) {
case SHAPE_PLANE:
free((PLANE *)ObjectArray[i]->Shape);
break;
case SHAPE_SPHERE:
free((SPHERE *)ObjectArray[i]->Shape);
break;
case SHAPE_ELLIPSOID:
free((ELLIPSOID *)ObjectArray[i]->Shape);
break;
case SHAPE_TRIANGLE:
free((TRIANGLE *)ObjectArray[i]->Shape);
break;
case SHAPE_BOX:
free((BOX *)ObjectArray[i]->Shape);
break;
case SHAPE_DISC:
free((DISC *)ObjectArray[i]->Shape);
break;
case SHAPE_CYLINDER:
free((CYLINDER *)ObjectArray[i]->Shape);
break;
}
free(ObjectArray[i]);
ObjectArray[i]=NULL;
}
}
if(NumLights>0) {
for(i=0;i<NumLights;i++) {
free(LightArray[i]);
LightArray[i]=NULL;
}
}
}
/*****************************************************************
*
* Transform handling routines
*
*****************************************************************/
void ClearTransform(TRANSFORM *t)
{
int i;
t->NumTransforms=0L;
for(i=0;i<10;i++) {
t->Entry[i].Type=TRANSFORM_NONE;
t->Entry[i].Values.x=t->Entry[i].Values.y=t->Entry[i].Values.z=0.0;
}
}
void CopyTransform(TRANSFORM *t2, TRANSFORM *t1)
{
int i;
t2->NumTransforms=t1->NumTransforms;
for(i=0;i<10;i++) {
t2->Entry[i].Type=t1->Entry[i].Type;
CopyVector(&t2->Entry[i].Values,&t1->Entry[i].Values);
}
}
void AddTransform(TRANSFORM *t2, TRANSFORM *t1)
{
long i,orignumtrans;
orignumtrans=t2->NumTransforms;
t2->NumTransforms+=t1->NumTransforms;
if(t2->NumTransforms>10L) t2->NumTransforms=10L;
for(i=orignumtrans;i<t2->NumTransforms;i++) {
t2->Entry[i].Type=t1->Entry[i].Type;
CopyVector(&t2->Entry[i].Values,&t1->Entry[i].Values);
}
}